package com.dongdongshop.txmessage;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dongdongshop.pojo.TbOrder;
import com.dongdongshop.service.OrderService;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;

import javax.annotation.Resource;
import java.util.List;

@RocketMQTransactionListener(txProducerGroup = "tx-integral")
public class MqTxLister implements RocketMQLocalTransactionListener {

    @Reference
    private OrderService orderService;
    @Autowired
    private RedisTemplate redisTemplate;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 当我们本地执行成功后会向mq|返回
     *  COMMIT,
     *     ROLLBACK,
     *     UNKNOWN;
     * @param message 想要发送的信息
     * @param o 我们执行本地事务需要的数据
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        try {
            String body = new String((byte[]) message.getPayload());
            logger.info("本地事物处理，内容体：" + body);

            logger.info("更新订单支付状态,参数为：{}",o);
            int i = orderService.updateOrderStatus((List<TbOrder>) o);
            logger.info("更新订单支付状态成功,执行了{}条",i);
        }catch (Exception e){
            logger.error("本地事物执行失败,处理异常并rollback，原因：{}",e);
            //将错误状态保存到redis
            redisTemplate.opsForValue().set(message.getHeaders().getId().toString(),"2");
            //处理失败返回rollback
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        //将成功状态保存到redis
        redisTemplate.opsForValue().set(message.getHeaders().getId().toString(),"1");
        //处理成功，返回commit
        return RocketMQLocalTransactionState.COMMIT;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        String status = (String)redisTemplate.opsForValue().get(message.getHeaders().getId());
        if ("1".equals(status)){//处理本地事物成功
            //提交
            return RocketMQLocalTransactionState.COMMIT;
        }else if ("2".equals(status)){//处理本地事物失败
            //回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        }else {
            //否则返回UNKNOWN
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}
